Mirror changes to x86 un/mask_evtchn
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 14 Dec 2005 19:02:37 +0000 (13:02 -0600)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 14 Dec 2005 19:02:37 +0000 (13:02 -0600)
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c

index e8f9f863e90d07b236c68f102d40c1104f2a7e6d..90a76639103a1b4625bd7717df4b5b94e13f69ad 100644 (file)
@@ -45,6 +45,47 @@ static struct {
  */
 static spinlock_t irq_mapping_update_lock;
 
+void mask_evtchn(int port)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
+       synch_set_bit(port, &s->evtchn_mask[0]);
+}
+EXPORT_SYMBOL(mask_evtchn);
+
+void unmask_evtchn(int port)
+{
+       shared_info_t *s = HYPERVISOR_shared_info;
+       unsigned int cpu = smp_processor_id();
+       vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
+
+#if 0  // FIXME: diverged from x86 evtchn.c
+       /* Slow path (hypercall) if this is a non-local port. */
+       if (unlikely(cpu != cpu_from_evtchn(port))) {
+               evtchn_op_t op = { .cmd = EVTCHNOP_unmask,
+                                  .u.unmask.port = port };
+               (void)HYPERVISOR_event_channel_op(&op);
+               return;
+       }
+#endif
+
+       synch_clear_bit(port, &s->evtchn_mask[0]);
+
+       /*
+        * The following is basically the equivalent of 'hw_resend_irq'. Just
+        * like a real IO-APIC we 'lose the interrupt edge' if the channel is
+        * masked.
+        */
+       if (synch_test_bit(port, &s->evtchn_pending[0]) && 
+           !synch_test_and_set_bit(port / BITS_PER_LONG,
+                                   &vcpu_info->evtchn_pending_sel)) {
+               vcpu_info->evtchn_upcall_pending = 1;
+               if (!vcpu_info->evtchn_upcall_mask)
+                       force_evtchn_callback();
+       }
+}
+EXPORT_SYMBOL(unmask_evtchn);
+
+
 #define unbound_irq(e) (VALID_EVTCHN(e) && (!evtchns[(e)].opened))
 int bind_virq_to_irqhandler(
        unsigned int virq,